package com.joker.demo.admin.util;

import java.time.*;
import java.util.Date;
import java.util.Objects;

/**
 * LocalDateTime 与 Date 转换工具类
 * 提供安全的日期时间转换方法，支持指定时区
 */
public final class DateTimeConverterUtil {

    private DateTimeConverterUtil() {
        throw new UnsupportedOperationException("这是一个工具类，不能被实例化");
    }

    // 常用时区常量
    public static final ZoneId UTC_ZONE = ZoneId.of("UTC");
    public static final ZoneId SHANGHAI_ZONE = ZoneId.of("Asia/Shanghai");
    public static final ZoneId SYSTEM_DEFAULT_ZONE = ZoneId.systemDefault();

    /**
     * 将 LocalDateTime 转换为 Date（使用系统默认时区）
     *
     * @param localDateTime 要转换的 LocalDateTime，不能为null
     * @return 对应的 Date 对象
     * @throws IllegalArgumentException 如果参数为null
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return toDate(localDateTime, SYSTEM_DEFAULT_ZONE);
    }

    /**
     * 将 LocalDateTime 转换为 Date（指定时区）
     *
     * @param localDateTime 要转换的 LocalDateTime，不能为null
     * @param zoneId        时区，不能为null
     * @return 对应的 Date 对象
     * @throws IllegalArgumentException 如果任何参数为null
     */
    public static Date toDate(LocalDateTime localDateTime, ZoneId zoneId) {
        Objects.requireNonNull(localDateTime, "localDateTime 不能为null");
        Objects.requireNonNull(zoneId, "zoneId 不能为null");
        
        return Date.from(localDateTime.atZone(zoneId).toInstant());
    }

    /**
     * 将 LocalDate 转换为 Date（使用系统默认时区，时间部分设为00:00:00）
     *
     * @param localDate 要转换的 LocalDate，不能为null
     * @return 对应的 Date 对象（时间部分为当天的开始时刻）
     * @throws IllegalArgumentException 如果参数为null
     */
    public static Date toDate(LocalDate localDate) {
        return toDate(localDate, SYSTEM_DEFAULT_ZONE);
    }

    /**
     * 将 LocalDate 转换为 Date（指定时区，时间部分设为00:00:00）
     *
     * @param localDate 要转换的 LocalDate，不能为null
     * @param zoneId    时区，不能为null
     * @return 对应的 Date 对象（时间部分为当天的开始时刻）
     * @throws IllegalArgumentException 如果任何参数为null
     */
    public static Date toDate(LocalDate localDate, ZoneId zoneId) {
        Objects.requireNonNull(localDate, "localDate 不能为null");
        Objects.requireNonNull(zoneId, "zoneId 不能为null");
        
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }

    /**
     * 将 Date 转换为 LocalDateTime（使用系统默认时区）
     *
     * @param date 要转换的 Date，不能为null
     * @return 对应的 LocalDateTime 对象
     * @throws IllegalArgumentException 如果参数为null
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return toLocalDateTime(date, SYSTEM_DEFAULT_ZONE);
    }

    /**
     * 将 Date 转换为 LocalDateTime（指定时区）
     *
     * @param date    要转换的 Date，不能为null
     * @param zoneId  时区，不能为null
     * @return 对应的 LocalDateTime 对象
     * @throws IllegalArgumentException 如果任何参数为null
     */
    public static LocalDateTime toLocalDateTime(Date date, ZoneId zoneId) {
        Objects.requireNonNull(date, "date 不能为null");
        Objects.requireNonNull(zoneId, "zoneId 不能为null");
        
        return date.toInstant().atZone(zoneId).toLocalDateTime();
    }

    /**
     * 将 Date 转换为 LocalDate（使用系统默认时区）
     *
     * @param date 要转换的 Date，不能为null
     * @return 对应的 LocalDate 对象
     * @throws IllegalArgumentException 如果参数为null
     */
    public static LocalDate toLocalDate(Date date) {
        return toLocalDate(date, SYSTEM_DEFAULT_ZONE);
    }

    /**
     * 将 Date 转换为 LocalDate（指定时区）
     *
     * @param date    要转换的 Date，不能为null
     * @param zoneId  时区，不能为null
     * @return 对应的 LocalDate 对象
     * @throws IllegalArgumentException 如果任何参数为null
     */
    public static LocalDate toLocalDate(Date date, ZoneId zoneId) {
        Objects.requireNonNull(date, "date 不能为null");
        Objects.requireNonNull(zoneId, "zoneId 不能为null");
        
        return date.toInstant().atZone(zoneId).toLocalDate();
    }

    /**
     * 安全地转换 Date（处理null值）
     *
     * @param date 可能为null的Date对象
     * @param zoneId 时区，不能为null
     * @return 如果date为null则返回null，否则返回转换后的LocalDateTime
     */
    public static LocalDateTime toLocalDateTimeSafely(Date date, ZoneId zoneId) {
        if (date == null) {
            return null;
        }
        return toLocalDateTime(date, zoneId);
    }

    /**
     * 安全地转换 LocalDateTime（处理null值）
     *
     * @param localDateTime 可能为null的LocalDateTime对象
     * @param zoneId 时区，不能为null
     * @return 如果localDateTime为null则返回null，否则返回转换后的Date
     */
    public static Date toDateSafely(LocalDateTime localDateTime, ZoneId zoneId) {
        if (localDateTime == null) {
            return null;
        }
        return toDate(localDateTime, zoneId);
    }
}